<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>铜锁SM2、SM3、SM4在线加密解密</title>
    <link rel="stylesheet" href="//unpkg.com/layui@2.6.8/dist/css/layui.css"/>
    <script src="//unpkg.com/layui@2.6.8/dist/layui.js"></script>
</head>
<body>
<div style="padding: 20px 20px">
    <div class="layui-tab">
        <ul class="layui-tab-title">
            <li class="layui-this">SM4加解密算法</li>
            <li>SM3杂凑算法</li>
            <li>SM2签名和验签</li>
        </ul>
        <div class="layui-tab-content">
            <div class="layui-tab-item layui-show">
                <div class="layui-row layui-anim-scale pt10" style="width: 100%;">
                    <div class="layui-col-md5">
                    <textarea style="resize: none;min-height: 280px;"
                              placeholder="在此输入明文，选择对应的加密方式，也可以加入密钥，然后加密即可。"
                              class="layui-textarea w99 fl m-h100" id="msg_source"></textarea>
                    </div>
                    <div class="layui-col-md2">
                        <form class="layui-form" action="" onsubmit="return !1;">
                            <div class="layui-form-item layui-col-md-offset2">
                                <div class="layui-input-inline fr w200 xpswd"><input type="text" name="text" id="pwd"
                                                                                     placeholder="在此输入密钥"
                                                                                     autocomplete="off"
                                                                                     class="layui-input">
                                </div>
                            </div>
                            <div class="layui-form-item layui-col-md-offset2">
                                <div class="layui-input-inline fr w200 mbt">
                                    <button class="layui-btn" onclick="decrypt();"><i class="layui-icon m-hide"></i>解密
                                    </button>
                                    <button class="layui-btn" onclick="encrypt();">加密<i
                                            class="layui-icon m-hide"></i>
                                    </button>
                                </div>
                            </div>
                        </form>
                    </div>
                    <div class="layui-col-md5"><textarea name="cipher" class="layui-textarea w99 fr "
                                                         placeholder="加密后的密文会显示在这里。也可以是待解密的密文。"
                                                         style="resize: none;min-height: 280px;" id="encrypt_result"
                                                         ondblclick="this.focus();this.select();"></textarea></div>
                </div>
            </div>
            <div class="layui-tab-item">
                <div>
                    <textarea style="resize: none;height: 200px;" placeholder="原文放到这里即可。"
                              class="layui-textarea w99 fl " id="source" maxlength="1000"></textarea>
                </div>
                <div style="display: inline-block;margin-top: 10px;margin-bottom:20px;">
                    <button class="layui-btn" id="ensm3" onclick="ensm3()">SM3加密<i class="layui-icon"></i></button>
                </div>
            </div>
            <div class="layui-tab-item">
                <div>
                    <button type="button" class="layui-btn" id="sign_file">
                        <i class="layui-icon">&#xe67c;</i>上传需要签名的文件
                    </button>

                    <div style="display: inline-block;margin-top: 10px;margin-bottom:20px;">
                        <button class="layui-btn" id="sign" onclick="download()">下载签名文件<i class="layui-icon"></i>
                        </button>
                    </div>
                </div>

                <div>
                    <button type="button" class="layui-btn" id="upload_origin_file">
                        <i class="layui-icon">&#xe67c;</i>上传源文件
                    </button>

                    <button type="button" class="layui-btn" id="upload_sign_file">
                        <i class="layui-icon">&#xe67c;</i>上传签名文件
                    </button>

                    <div style="display: inline-block;margin-top: 10px;margin-bottom:20px;">
                        <button class="layui-btn" onclick="verify()">验证签名<i class="layui-icon"></i></button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
<script>
    function ajaxRequest(url, data, onSuccess, onError) {
        var xhr = new XMLHttpRequest();

        xhr.open('POST', url, true);

        xhr.onreadystatechange = function () {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200) {
                    onSuccess(JSON.parse(xhr.responseText));
                } else {
                    onError(JSON.parse(xhr.statusText));
                }
            }
        };

        var formData = new FormData();

        for (var key in data) {
            formData.append(key, data[key]);
        }
        xhr.send(formData);
    }

    // 获取 id 为 msg_source 的元素
    var source = document.getElementById('msg_source');
    var source_text = document.getElementById('source');
    var pwd = document.getElementById('pwd');

    // 获取 id 为 encrypt_result 的元素
    var result = document.getElementById('encrypt_result');

    function encrypt() {
        console.log('加密')
        const v = source.value
        const pass = pwd.value
        if (!v || v === '') {
            return alert('加密数据为空')
        }
        if (!pass || pass === '') {
            return alert('密钥为空')
        }


        ajaxRequest('http://127.0.0.1:5000/sm4_cbc_encrypt', {'msg': v.trim(), 'key': pass.trim()}, function (res) {
            console.log(res);
            result.value = res.output;
        }, function (err) {
            console.log(err);
        })
    }

    function decrypt() {

        console.log('解密')
        const v = result.value.trim()
        if (!v || v === '') {
            return alert('解密数据为空')
        }

        const pass = pwd.value.trim()
        if (!pass || pass === '') {
            return alert('密钥为空')
        }

        ajaxRequest('http://127.0.0.1:5000/sm4_cbc_decrypt', {'msg': v, 'key': pass}, function (res) {
            console.log(res);
            if (res.error !== '') {
                return layer.alert('解密失败:' + res.error, {'icon': 2});
            }
            source.value = res.output;
        }, function (err) {
            console.log(err);
        })
    }

    function ensm3() {
        console.log('sm3加密')
        const v = source_text.value
        if (!v || v === '') {
            return alert('加密数据为空')
        }
        ajaxRequest('http://127.0.0.1:5000/sm3_dgst', {'msg': v.trim()}, function (res) {
            console.log(res);
            source_text.value = res.output;
        }, function (err) {
            console.log(err);
        })
    }

    var file_path = ''
    var origin_file_path = ''
    var sign_file_path = ''

    function download() {
        console.log('file_path')
        if (!file_path || file_path === '') {
            return alert('签名文件未上传')
        }

        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://127.0.0.1:5000/download', true);
        xhr.responseType = 'blob';

        xhr.onload = function () {
            if (xhr.status === 200) {
                var blob = new Blob([xhr.response], {type: 'application/octet-stream'});
                var a = document.createElement('a');
                a.href = window.URL.createObjectURL(blob);
                a.download = Math.floor(Math.random() * 10000) + '_sign_file';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                layer.alert('下载签名文件成功', {'icon': 1});
            } else {
                console.log(xhr.statusText);
            }
        };

        var fData = new FormData();
        fData.append('file_path', file_path);
        console.log(file_path);
        console.log(fData)
        xhr.send(fData);
    }

    function verify() {
        console.log('verify')
        const v = source.value
        if (!origin_file_path || origin_file_path === '') {
            return alert('原始文件未上传！')
        }
        if (!sign_file_path || sign_file_path === '') {
            return alert('签名文件未上传！')
        }

        ajaxRequest('http://127.0.0.1:5000/sm2_verify', {
            'file_path': origin_file_path,
            'sign_file_path': sign_file_path
        }, function (res) {
            console.log(res);
            layer.alert(res.output);
        }, function (err) {
            console.log(err);
        })
    }

    uploadFile('#sign_file', function (res) {
        ajaxRequest('http://127.0.0.1:5000/sm2_sign', {'path': res.path}, function (sign_res) {
            file_path = sign_res.path
        }, function (sign_err) {
            console.log(sign_err);
        })
    })

    uploadFile('#upload_origin_file', function (res) {
        origin_file_path = res.path
    })

    uploadFile('#upload_sign_file', function (res) {
        sign_file_path = res.path
    })

    function uploadFile(elem, doneCallback, errorCallback) {
        layui.use('upload', function () {
            var upload = layui.upload;
            //执行实例
            var uploadInst = upload.render({
                elem: elem,
                accept: 'file',
                url: 'http://127.0.0.1:5000/upload',
                done: function (res) {
                    doneCallback(res);
                },
                error: function () {
                    errorCallback();
                }
            });
        });
    }


</script>
</html>